<?php

namespace App\Jobs\Service;

use App\Models\Device;
use App\Models\User;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Log;

class UserLevelUpdateJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    // 结算等级的用户
    protected $user;

    // 结算等级的用户的直推人
    protected $zhituis;

    /**
     * UserLevelJob constructor.
     * @param User $user
     */
    public function __construct(User $user)
    {
        $this->user = $user;
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        // 更新当前节点到根节点路径上所有人的用户等级
        $users = User::where('_lft', '<=', $this->user->_lft)
            ->where('_rgt', '>=', $this->user->_rgt)
            ->orderBy('id', 'desc')
            ->get();
        foreach ($users as $user) {
            try {
                $this->updateLevel($user);
            } catch (\Exception $exception) {
                Log::info("====用户等级更新失败，user_id:{$user->id}====");
                Log::error($exception);
            }
        }
    }

    /**
     * @param User $user.
     * 1.初级矿工：共享满8T有效存储空间，即为初级矿工，在分享其它矿工时获得爆块开采奖励
     * L1：直接分享8T以内为L1，市场新增部分获得矿工抵押币10%的爆块开采；
     * L2：直接分享9-16T为L2，市场新增部分获得矿工抵押币12%的爆块开采；
     * L3：直接分享17-24T为L3，市场新增部分获得矿工抵押币14%的爆块开采；
     * L4：直接分享25-32T为L4，市场新增部分获得矿工抵押币16%的爆块开采；
     * L5：直接分享33-40T为L5，市场新增部分获得矿工抵押币18%的爆块开采；
     * 间接分享：无
     * 2.高级矿工：共享满8T有效存储空间，并且直接分享3个初级矿工，即为高级矿工，其后分享其它矿工时获得矿工抵押币量21%的爆块开采；
     * 3.顶级矿工：共享满8T有效存储空间，并且直接分享3个高级矿工，即为顶级矿工，在分享其它矿工时获得矿工抵押币量24%的爆块开采；
     * 4.超级节点：共享满8T有效存储空间，并且分享的3个不同社区中产生顶级矿工，即为超级节点，在分享其它矿工时获得矿工抵押币量27%的爆块开采；
     * 5.顶级节点：共享满8T有效存储空间，并且分享3个不同社区中产生超级节点（3个区），即为顶级节点，在分享其它矿工时获得矿工抵押币量30%的爆块开采；
     */
    private function updateLevel(User $user)
    {
        // 自有算力
        $self_order = Device::where('user_id', $user->id)->sum('use');
        if ($self_order < 8) {
            $level = 0; // 少于8T
            $level_type = 0;
        } else {
            // 直推用户
            $this->zhituis = User::where('parent_id', $user->id)->get();
            if (count($this->zhituis) < 3) { // 少于3个社区，只能是初级矿工
                $level = 1;
                $level_type = $this->getLevelType();
            } else { // 可能高级矿工、顶级矿工、超级节点、顶级节点
                if ($this->_checkLevel6($user)) { // 顶级节点检测
                    $level = 6;
                    $level_type = 0;
                } else if ($this->_checkLevel5($user)) { // 顶级节点检测
                    $level = 5;
                    $level_type = 0;
                } else if ($this->_checkLevel4($user)) { // 超级节点检测
                    $level = 4;
                    $level_type = 0;
                } else if ($this->_checkLevel3($user)) { // 顶级矿工检测
                    $level = 3;
                    $level_type = 0;
                } else if ($this->_checkLevel2($user)) { // 高级矿工检测
                    $level = 2;
                    $level_type = 0;
                }else { // 只能是初级矿工
                    $level = 1;
                    $level_type = $this->getLevelType();
                }
            }
        }

        // 如果管理员指定了等级，使用管理员指定的等级
        if ($user->admin_level > 0) {
            switch ($user->admin_level) {
                case 1:
                    $level = 1;
                    $level_type = 1;
                    break;
                case 2:
                case 3:
                case 4:
                case 5:
                    $level = $user->admin_level;
                    $level_type = 0;
                    break;
                default:
                    break;

            }
        }

        $user->vip_level = $level;
        $user->level_type = $level_type;
        $user->save();
    }

    /**
     * 计算初级矿工级别.
     * @return int
     */
    public function getLevelType()
    {
        // 直接分享算力
        $zhitui_order = Device::whereIn('user_id', $this->zhituis->pluck('id'))->sum('use');
        // 计算初级矿工的级别
        if ($zhitui_order <= 8) {
            $level_type = 1;
        }  else if (9 <= $zhitui_order && $zhitui_order <= 16) {
            $level_type = 2;
        } else if (17 <= $zhitui_order && $zhitui_order <= 24) {
            $level_type = 3;
        } else if (25 <= $zhitui_order && $zhitui_order <= 32) {
            $level_type = 4;
        } else if (33 <= $zhitui_order) {
            $level_type = 5;
        } else {
            $level_type = 1;
        }

        return $level_type;
    }

    /**
     * 检测是否为顶级节点：共享满8T有效存储空间，并且分享3个不同社区中产生超级节点（3个区），即为顶级节点，在分享其它矿工时获得矿工抵押币量30%的爆块开采；
     * @return bool
     */
    public function _checkLevel6($user)
    {
        $count = 0; // 伞下超级节点个数
        foreach ($this->zhituis as $child) {
            $level_is_count = User::where('_lft', '>=', $child->_lft)
                ->where('_rgt', '<=', $child->_rgt)
                ->where('vip_level', '>=', 4)
                ->count();
            if ($level_is_count > 0) {
                $count++;
            }
            if ($count >= 3) {
                break;
            }
        }

        if ($count < 3) {
            return false;
        }

        return true;
    }

    /**
     * 检测是否为顶级节点：共享满8T有效存储空间，并且分享3个不同社区中产生超级节点（3个区），即为顶级节点，在分享其它矿工时获得矿工抵押币量30%的爆块开采；
     * @return bool
     */
    public function _checkLevel5($user)
    {
        $count = 0; // 伞下超级节点个数
        foreach ($this->zhituis as $child) {
            $level_is_count = User::where('_lft', '>=', $child->_lft)
                ->where('_rgt', '<=', $child->_rgt)
                ->where('vip_level', '>=', 4)
                ->count();
            if ($level_is_count > 0) {
                $count++;
            }
            if ($count >= 3) {
                break;
            }
        }

        if ($count < 3) {
            return false;
        }

        return true;
    }

    /**
     * 检测是否为超级节点：共享满8T有效存储空间，并且分享的3个不同社区中产生顶级矿工，即为超级节点，在分享其它矿工时获得矿工抵押币量27%的爆块开采；
     * @return bool
     */
    public function _checkLevel4($user)
    {
        $count = 0; // 伞下顶级矿工个数
        foreach ($this->zhituis as $child) {
            $level_is_count = User::where('_lft', '>=', $child->_lft)
                ->where('_rgt', '<=', $child->_rgt)
                ->where('vip_level', '>=', 3)
                ->count();
            if ($level_is_count > 0) {
                $count++;
            }
            if ($count >= 3) {
                break;
            }
        }

        if ($count < 3) {
            return false;
        }

        return true;
    }

    /**
     * 检测是否为顶级矿工：共享满8T有效存储空间，并且直接分享3个高级矿工，即为顶级矿工，在分享其它矿工时获得矿工抵押币量24%的爆块开采；
     * @return bool
     */
    public function _checkLevel3($user)
    {
        $count = 0; // 直推高级矿工个数
        foreach ($this->zhituis as $child) {
            if ($child->vip_level >= 2) {
                $count++;
            }
            if ($count >= 3) {
                break;
            }
        }

        if ($count < 3) {
            return false;
        }

        return true;
    }

    /**
     * 检测是否为高级矿工：共享满8T有效存储空间，并且直接分享3个初级矿工，即为高级矿工，其后分享其它矿工时获得矿工抵押币量21%的爆块开采；
     * @return bool
     */
    public function _checkLevel2($user)
    {
        $count = 0; // 直推初级矿工个数
        foreach ($this->zhituis as $child) {
            if ($child->vip_level >= 1) {
                $count++;
            }
            if ($count >= 3) {
                break;
            }
        }

        if ($count < 3) {
            return false;
        }

        return true;
    }
}
